package hollycrm.com.uip;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.pjsip.pjsua2.CallInfo;
import org.pjsip.pjsua2.pjsip_inv_state;
import org.pjsip.pjsua2.pjsip_role_e;

import hollycrm.com.libuip.UIPClient;
import hollycrm.com.libuip.UIPUserConfig;
import hollycrm.com.libuip.http.UIPConfig;
import hollycrm.com.libuip.sip.UIPCall;
import hollycrm.com.libuip.socket.UIPMessage;
import hollycrm.com.libuip.socket.UIPMessageID;
import hollycrm.com.uip.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity
        implements UIPActions,PhoneActions,UIPClient.UIPListener {

    private TextView socketStatusTv,sipStatusTv;
    private Button acceptBt,hangupBt;
    private EditText sipNo;

    private UIPClient client;

    private UIPConfig config;

    private UIPCall currentCall;

    private String ip = "60.166.38.219";
    private int port = 18081;
    private String workNo = "2003";
    private String deviceNo = "2003";

    private PhoneStatus phoneStatus;
    private LogMessage logMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding activityMainBinding =
                DataBindingUtil.setContentView(this,R.layout.activity_main);
        activityMainBinding.setActions(this);
        activityMainBinding.setPhoneActions(this);
        phoneStatus = new PhoneStatus();
        phoneStatus.setLastPhoneStatus("null");
        logMessage = new LogMessage();
        logMessage.setCurrentStatus("null");
        activityMainBinding.setPhoneStatus(phoneStatus);
        activityMainBinding.setStatus(logMessage);
        socketStatusTv = activityMainBinding.socketStatus;
        sipStatusTv = activityMainBinding.callState;
        acceptBt = activityMainBinding.accept;
        hangupBt = activityMainBinding.hangup;
        sipNo = activityMainBinding.outCallNo;

        client = new UIPClient(getApplicationContext(),newConfig());

        Log.d("thread main",Thread.currentThread().toString());
    }

    @Override
    protected void onStart() {
        super.onStart();
        client.registerUIPListener(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        client.unregisterUIPListener(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (client != null)
            client.disconnect();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final int id = item.getItemId();
        switch (id) {
            case R.id.action_setting:
                dlgConfig();
                return true;
            case R.id.action_sip:

        }
        return super.onOptionsItemSelected(item);
    }

    private void dlgConfig() {
        View view = getLayoutInflater().inflate(R.layout.dig_config,null);
        final TextInputEditText ipEt = (TextInputEditText) view.findViewById(R.id.uip_server_ip);
        final TextInputEditText portEt = (TextInputEditText) view.findViewById(R.id.uip_server_port);
        final TextInputEditText deviceEt = (TextInputEditText) view.findViewById(R.id.device_no);
        final TextInputEditText workEt = (TextInputEditText) view.findViewById(R.id.work_no);
        ipEt.setText(ip);
        portEt.setText(""+port);
        deviceEt.setText(deviceNo);
        workEt.setText(workNo);
        AlertDialog alertDialog = new AlertDialog.Builder(this)
                .setTitle("账号设置")
                .setView(view).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ip = ipEt.getText().toString();
                        port = Integer.valueOf(portEt.getText().toString());
                        deviceNo = deviceEt.getText().toString();
                        workNo = workEt.getText().toString();
                    }
                }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .create();
        alertDialog.show();
    }

    @Override
    public void connect(View view) {
        client.connect();
    }

    @Override
    public void disconnect(View view) {
        client.disconnect();
    }

    @Override
    public void login(View view) {
        client.sendMessage(UIPMessage.getSignIn(
                workNo,deviceNo,config.phoneconfig.SkillDesc
        ));
    }
    @Override
    public void logout(View view) {
        client.sendMessage(UIPMessage.getSignOut(
                workNo
        ));
    }
    @Override
    public void ready(View view) {
        client.sendMessage(UIPMessage.getAgentReady(workNo));
    }
    @Override
    public void notReady(View view) {
        client.sendMessage(UIPMessage.getAgentNotReady(workNo));
    }
    @Override
    public void reset(View view) {
        client.sendMessage(UIPMessage.getReset(workNo));
    }

    @Override
    public void makeCall(View view) {
        client.sendMessage(UIPMessage.getMakeCall(
                workNo,deviceNo,1,sipNo.getText().toString(),workNo
        ));
    }
    @Override
    public void sipCall(View view) {
        // no op
    }

    @Override
    public void accept(View view) {
        if (currentCall == null) return;
        currentCall.accept();
    }

    @Override
    public void reject(View view) {
        if (currentCall == null) return;
        currentCall.hangup();
    }

    @Override
    public void hangup(View view) {
        if (currentCall == null) return;
        currentCall.hangup();
    }

    private void logError(String error,Throwable e) {
        if(!TextUtils.isEmpty(error)) {
            socketStatusTv.append("\n");
            socketStatusTv.append(error);
        }
        if (e != null) {
            socketStatusTv.append("\n");
            socketStatusTv.append(e.getLocalizedMessage());
        }
    }

    @Override
    public void updateCallStatus(CallInfo ci) {
        String call_state = "";

        if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAC) {
            acceptBt.setVisibility(View.GONE);
        }

        if (ci.getState().swigValue() <
                pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue()) {
            if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAS) {
                call_state = "Incoming call..";
                /* Default button texts are already 'Accept' & 'Reject' */
            } else {
                hangupBt.setText("Cancel");
                call_state = ci.getStateText();
            }
        } else if (ci.getState().swigValue() >=
                pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue()) {
            acceptBt.setVisibility(View.GONE);
            call_state = ci.getStateText();
            if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED) {
                hangupBt.setText("Hangup");
            } else if (ci.getState() ==
                    pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) {
                hangupBt.setText("OK");
                call_state = "Call disconnected: " + ci.getLastReason();
            }
        }

        sipNo.setText(ci.getRemoteUri());
        sipStatusTv.setText(call_state);
    }

    @Override
    public void incomingCall(UIPCall call) {
        currentCall = call;
        // todo show the call activity or fragment
    }

    @Override
    public void updatePhoneRegisterStatus(boolean isSuccess, String status) {
        Toast.makeText(this,String.format("注册: %s",status),Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onGetUIPConfig(UIPConfig config) {
        this.config = config;
    }

    @Override
    public void onGetUIPConfigError(Throwable t) {

    }

    @Override
    public void onError(int code, Throwable t) {
        logError(null,t);
        Toast.makeText(this,t.getMessage(),Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onResp(UIPMessage resp) {

        appendLogText(resp.id);
    }

    @Override
    public void onEvent(UIPMessage event) {
        appendLogText(event.id);
    }

    @Override
    public void onConnected() {
        appendLogText("连结成功");
    }

    @Override
    public void onDisConnected() {
        appendLogText("断开连结");
    }

    private void appendLogText(String log) {
        // append the new string
        socketStatusTv.append(log + "\n");
        // find the amount we need to scroll.  This works by
        // asking the TextView's internal layout for the position
        // of the final line and then subtracting the TextView's height
        final int scrollAmount = socketStatusTv.getLayout().getLineTop(socketStatusTv.getLineCount()) - socketStatusTv.getHeight();
        // if there is no need to scroll, scrollAmount will be <=0
        if (scrollAmount > 0)
            socketStatusTv.scrollTo(0, scrollAmount);
        else
            socketStatusTv.scrollTo(0, 0);
    }

    public UIPUserConfig newConfig() {
        return new UIPUserConfig(workNo,deviceNo,ip,port,false);
    }

}
